package com.cc.blog.admin.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.cc.blog.admin.domain.dto.AddCategoryReqDTO;
import com.cc.blog.admin.domain.dto.DeleteCategoryReqDTO;
import com.cc.blog.admin.domain.dto.FindCategoryPageListReqDTO;
import com.cc.blog.admin.domain.vo.FindCategoryPageListRspVO;
import com.cc.blog.admin.mapper.ArticleCategoryRelMapper;
import com.cc.blog.admin.mapper.CategoryMapper;
import com.cc.blog.admin.model.ArticleCategoryRelDO;
import com.cc.blog.admin.model.CategoryDO;
import com.cc.blog.admin.service.AdminCategoryService;
import com.cc.blog.common.enums.CodeEnum;
import com.cc.blog.common.exception.BusinessException;
import com.cc.blog.common.model.SelectRspVO;
import com.cc.blog.common.utils.PageResult;
import com.cc.blog.common.utils.Result;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDate;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @Author cc
 * @Date 2024/7/10 14:03
 */
@Service
@Slf4j
@AllArgsConstructor
public class AdminCategoryServiceImpl implements AdminCategoryService {

    private final CategoryMapper categoryMapper;
    private final ArticleCategoryRelMapper articleCategoryRelMapper;

    @Override
    public Result addCategory(AddCategoryReqDTO addCategoryReqDTO) {
        String categoryName = addCategoryReqDTO.getName();
        // 先判断该分类是否已经存在
        CategoryDO categoryDO = categoryMapper.selectByName(categoryName);
        if (Objects.nonNull(categoryDO)) {
            log.warn("分类名称： {}, 此分类已存在", categoryName);
            throw new BusinessException(CodeEnum.CATEGORY_NAME_IS_EXISTED);
        }
        // 构建 DO 类
        CategoryDO insertCategoryDO = CategoryDO.builder()
                .name(addCategoryReqDTO.getName().trim())
                .build();
        // 执行 insert
        categoryMapper.insert(insertCategoryDO);

        return Result.success();
    }

    @Override
    public PageResult findCategoryList(FindCategoryPageListReqDTO queryDto) {
        // 分页对象(查询第几页、每页多少数据)
        Page<CategoryDO> page = new Page<>(queryDto.getCurrent(), queryDto.getSize());

        String name = queryDto.getName();
        LocalDate startDate = queryDto.getStartDate();
        LocalDate endDate = queryDto.getEndDate();

        // 构建查询条件
        LambdaQueryWrapper<CategoryDO> wrapper = Wrappers.<CategoryDO>lambdaQuery()
                // like 模块查询
                .like(StringUtils.isNotBlank(name), CategoryDO::getName, name.trim())
                // 大于等于 startDate
                .ge(Objects.nonNull(startDate), CategoryDO::getCreateTime, startDate)
                // 小于等于 endDate
                .le(Objects.nonNull(endDate), CategoryDO::getCreateTime, endDate)
                // 按创建时间倒叙
                .orderByDesc(CategoryDO::getCreateTime);

        // 执行分页查询
        Page<CategoryDO> categoryDOPage = categoryMapper.selectPage(page, wrapper);
        List<CategoryDO> categoryDOS = categoryDOPage.getRecords();
        // DO 转 VO
        List<FindCategoryPageListRspVO> vos = null;
        if (!CollectionUtils.isEmpty(categoryDOS)) {
            vos = categoryDOS.stream()
                    .map(categoryDO -> FindCategoryPageListRspVO.builder()
                            .id(categoryDO.getId())
                            .name(categoryDO.getName())
                            .createTime(categoryDO.getCreateTime())
                            .articlesTotal(categoryDO.getArticlesTotal())
                            .build())
                    .collect(Collectors.toList());
        }
        return PageResult.success(categoryDOPage, vos);
    }

    @Override
    public Result deleteCategory(DeleteCategoryReqDTO deleteCategoryReqDTO) {
        // 分类 ID
        Long categoryId = deleteCategoryReqDTO.getId();
        ArticleCategoryRelDO articleCategoryRelDO = articleCategoryRelMapper.selectOne(Wrappers.<ArticleCategoryRelDO>lambdaQuery()
                .eq(ArticleCategoryRelDO::getCategoryId, categoryId)
                .last("LIMIT 1"));
        if (Objects.nonNull(articleCategoryRelDO)) {
            log.warn("==> 此分类下包含文章，无法删除，categoryId: {}", categoryId);
            throw new BusinessException(CodeEnum.CATEGORY_CAN_NOT_DELETE);
        }
        // 删除分类
        categoryMapper.deleteById(categoryId);
        return Result.success();
    }

    @Override
    public Result findCategorySelectList() {
        // 查询所有分类
        List<CategoryDO> categoryDOS = categoryMapper.selectList(null);
        // DO 转 VO
        List<SelectRspVO> selectRspVOS = null;
        // 如果分类数据不为空
        if (!CollectionUtils.isEmpty(categoryDOS)) {
            // 将分类 ID 作为 Value 值，将分类名称作为 label 展示
            selectRspVOS = categoryDOS.stream()
                    .map(categoryDO -> SelectRspVO.builder()
                            .label(categoryDO.getName())
                            .value(categoryDO.getId())
                            .build())
                    .collect(Collectors.toList());
        }
        return Result.success(selectRspVOS);
    }
}
